package hsh.kernel;

import java.util.Hashtable;
import java.util.List;
import java.util.PriorityQueue;

import hsh.drivers.DeviceDriver;
import hsh.gui.LASh;
import hsh.gui.Shell;
import hsh.processor.Processor;
import hsh.util.Interruption;
import hsh.util.OSMode;
import hsh.util.Status;
import hshs.process.Process;
import hshsm.managers.DeviceManager;
import hshsm.managers.InterruptManager;
import hshsm.managers.Scheduler;

public class OperatingSystemKernel implements Runnable{

	private Scheduler scheduler;
	private InterruptManager interruptManager;
	private Processor processor;
	private OSMode osMode;
	private Process currentProcess;
	private Interruption interruption;
	private DeviceManager deviceManager;
	//private Shell shell;
	private LASh shell; //edited by lost :D
	
	public OperatingSystemKernel(Processor processor) {
		this.scheduler = new Scheduler();
		this.interruption = Interruption.NONE;
		this.interruptManager = new InterruptManager();
		this.processor = processor;
		this.deviceManager = new DeviceManager();
		//this.shell = Shell.createAndShowGui(this);
		this.shell = new LASh(this); //sSLost testes :D
		this.currentProcess = null;
		this.processor = Processor.getInstance();
		
		
		
	}
	
	
	public Scheduler getScheduler(){
		return this.scheduler;
	}
	
	
	public void executeUserProgram(){
		
		//System.out.println("executing process");
		if(currentProcess != null){
		   
			this.interruption = processor.executeProcess(currentProcess, 2);
			//System.out.println("entrou");
			
		}//else
			//System.out.println("nao entrou");
		
		
	
	}
	
	public void executeOperatingSystemTasks(){
		
		//handling interruptation
		
		if(this.interruption != Interruption.NONE){
			this.interruptManager.handleInterruptation(interruption,scheduler);
		}
		
		
		if(currentProcess != null &&  currentProcess.getStatus() == Status.READY ){
			scheduler.addReadyProcess(currentProcess);
		}
		
		if(currentProcess != null &&  currentProcess.getStatus() == Status.NEW ){
			scheduler.addReadyProcess(currentProcess);
		}
		
		if(currentProcess != null && currentProcess.getStatus() == Status.FINISHED){
			scheduler.addFinishedProcess(currentProcess);
		}
		
		
		
	     currentProcess = scheduler.nextProcess(); 
	   //  System.out.println("processo: "+currentProcess);
		
	}
	
	public void installDriver(DeviceDriver driver){
		this.deviceManager.installDriver(driver);
	}
	

	 
	public  final void run() {
       while(true){
			//System.out.println("executing os....");
			//swapping between the kernel and the program user
			executeOperatingSystemTasks();
			executeUserProgram();
		}
	}
	
}
